package com.umeox.sdk_ring

import com.umeox.sdk_ring.protocol.IAppProtocol
import com.umeox.sdk_ring.protocol.IRingProtocol
import java.io.File
import java.util.*

class RingProxy(private val macAddress: String) : IRingProtocol, IAppProtocol {

    companion object {
        private const val TAG = "RingProxy"
    }

    private val interaction = RingDeviceInteraction(macAddress, this)

    /**
     * 回调信息观察者集合
     */
    private val appProtocolObservers = arrayListOf<IAppProtocol>()

    /**
     * 对象锁
     */
    private val lock = Any()

    fun addAppProtocolObserver(appProtocol: IAppProtocol) {
        synchronized(lock) {
            if (!appProtocolObservers.contains(appProtocol)) {
                appProtocolObservers.add(appProtocol)
            }
        }
    }

    fun removeProtocolObserver(appProtocol: IAppProtocol) {
        synchronized(lock) {
            if (appProtocolObservers.contains(appProtocol)) {
                appProtocolObservers.remove(appProtocol)
            }
        }
    }

    /**
     * 销毁设备代理
     */
    fun destroy() {
        UMRingSdk.log(TAG, "销毁戒指设备代理")
        synchronized(lock) {
            appProtocolObservers.clear()
            interaction.destroy()
        }
    }

    override fun disConnectDevice() {
        interaction.getDefaultRingProtocolImpl().disConnectDevice()
    }

    override fun connectDevice() {
        interaction.getDefaultRingProtocolImpl().connectDevice()
    }

    override fun directConnectDevice() {
        interaction.directConnectDevice()
    }

    override fun syncCurrentTimeAndTimeFormat(
        date: Date?,
        is24Hour: Boolean?,
        showTime: Boolean,
        timeZone: Double
    ) {
        interaction.getDefaultRingProtocolImpl()
            .syncCurrentTimeAndTimeFormat(date, is24Hour, showTime, timeZone)
    }

    override fun getDeviceBatteryPower() {
        interaction.getDefaultRingProtocolImpl().getDeviceBatteryPower()
    }

    override fun flipDeviceScreen() {
        interaction.getDefaultRingProtocolImpl().flipDeviceScreen()
    }

    override fun startFindDevice() {
        interaction.getDefaultRingProtocolImpl().startFindDevice()
    }

    override fun stopFindDevice() {
        interaction.getDefaultRingProtocolImpl().stopFindDevice()
    }

    override fun getDeviceState() {
        interaction.getDefaultRingProtocolImpl().getDeviceState()
    }

    override fun getPrayerCountInformation(tick: String) {
        interaction.getDefaultRingProtocolImpl().getPrayerCountInformation(tick)
    }

    override fun getRealTimePrayerCount(tick: String) {
        interaction.getDefaultRingProtocolImpl().getRealTimePrayerCount(tick)
    }

    override fun shutdown() {
        interaction.getDefaultRingProtocolImpl().shutdown()
    }

    override fun setPrayerRemindersState(
        isOpen: Boolean,
        calculationMethodPosition: Int,
        juristicMethodPosition: Int,
        latitude: Double,
        longitude: Double,
        timeZone: Double
    ) {
        interaction.getDefaultRingProtocolImpl().setPrayerRemindersState(
            isOpen,
            calculationMethodPosition,
            juristicMethodPosition,
            latitude,
            longitude,
            timeZone
        )
    }

    override fun reboot(macAddress: String) {
        interaction.getDefaultRingProtocolImpl().reboot(macAddress)
    }

    override fun setPrayerReminders(
        isOpen: Boolean,
        startTime: String,
        endTime: String,
        intervalTime: Int
    ) {
        interaction.getDefaultRingProtocolImpl()
            .setPrayerReminders(isOpen, startTime, endTime, intervalTime)
    }

    override fun getDeviceCacheData() {
        interaction.getDefaultRingProtocolImpl().getDeviceCacheData()
    }

    override fun getDeviceConfigInfo() {
        interaction.getDefaultRingProtocolImpl().getDeviceConfigInfo()
    }

    override fun getDeviceLog() {
        interaction.getDefaultRingProtocolImpl().getDeviceLog()
    }

    override fun setDeviceScreenBrightness(brightness: Int) {
        interaction.getDefaultRingProtocolImpl().setDeviceScreenBrightness(brightness)
    }

    override fun setDeviceLanguage(languageType: Int) {
        interaction.getDefaultRingProtocolImpl().setDeviceLanguage(languageType)
    }

    override fun setCustomizeConvention(
        fajrAngle: Float,
        maghribIsMinutes: Boolean,
        maghribValue: Float,
        ishaIsMinutes: Boolean,
        ishaValue: Float
    ) {
        interaction.getDefaultRingProtocolImpl().setCustomizeConvention(
            fajrAngle,
            maghribIsMinutes,
            maghribValue,
            ishaIsMinutes,
            ishaValue
        )
    }

    override fun setStableConvention(index: Int) {
        interaction.getDefaultRingProtocolImpl().setStableConvention(index)
    }

    override fun setTasbihTask(enable: Boolean, targetNumber: Int, taskId: Int) {
        interaction.getDefaultRingProtocolImpl().setTasbihTask(enable, targetNumber, taskId)
    }

    override fun getTasbihTaskInfo(tick: String) {
        interaction.getDefaultRingProtocolImpl().getTasbihTaskInfo(tick)
    }

    override fun setShipNavigationMode() {
        interaction.getDefaultRingProtocolImpl().setShipNavigationMode()
    }

    override fun setScreenRestTime(time: Int) {
        interaction.getDefaultRingProtocolImpl().setScreenRestTime(time)
    }

    override fun setPrayerRemindConfig(configs: Array<Array<Int>>) {
        interaction.getDefaultRingProtocolImpl().setPrayerRemindConfig(configs)
    }

    override fun setCustomCountReminder(normal33: Boolean, normal100: Boolean, customValue: Int) {
        interaction.getDefaultRingProtocolImpl()
            .setCustomCountReminder(normal33, normal100, customValue)
    }

    override fun getPrayerRemindConfig() {
        interaction.getDefaultRingProtocolImpl()
            .getPrayerRemindConfig()
    }

    override fun setUserInfo(
        age: Int,
        gender: Int,
        height: Int,
        weight: Int,
        hrMax: Int,
        hrRest: Int,
        vo2max: Int
    ) {
        interaction.getDefaultRingProtocolImpl()
            .setUserInfo(age, gender, height, weight, hrMax, hrRest, vo2max)
    }

    override fun getCurrentStepNumber() {
        interaction.getDefaultRingProtocolImpl()
            .getCurrentStepNumber()
    }

    override fun getAllSleepData() {
        interaction.getDefaultRingProtocolImpl()
            .getAllSleepData()
    }

    override fun getAllStepData() {
        interaction.getDefaultRingProtocolImpl()
            .getAllStepData()
    }

    override fun pkeyOperation(write: Boolean, pkey: String) {
        interaction.getDefaultRingProtocolImpl()
            .pkeyOperation(write, pkey)
    }

    override fun n01ScreenTest(light: Boolean) {
        interaction.getDefaultRingProtocolImpl()
            .n01ScreenTest(light)
    }

    override fun gsensorTest() {
        interaction.getDefaultRingProtocolImpl()
            .gsensorTest()
    }

    override fun setTimeShowType(type: Int) {
        interaction.getDefaultRingProtocolImpl()
            .setTimeShowType(type)
    }

    override fun getWorshipCacheData(tick: String) {
        interaction.getDefaultRingProtocolImpl().getWorshipCacheData(tick)
    }

    override fun getRealtimeWorship() {
        interaction.getDefaultRingProtocolImpl().getRealtimeWorship()
    }

    override fun setLedTimeAndLight(lightTime: Int, light: Int) {
        interaction.getDefaultRingProtocolImpl().setLedTimeAndLight(lightTime, light)
    }

    override fun getSc01DeviceInfo() {
        interaction.getDefaultRingProtocolImpl().getSc01DeviceInfo()
    }

    override fun deviceInfraRedTest(enable: Boolean) {
        interaction.getDefaultRingProtocolImpl().deviceInfraRedTest(enable)
    }

    override fun deviceRadarTest(enable: Boolean) {
        interaction.getDefaultRingProtocolImpl().deviceRadarTest(enable)
    }

    override fun getAllWorshipCacheData() {
        interaction.getDefaultRingProtocolImpl().getAllWorshipCacheData()
    }

    override fun modifyWorshipNumberByIndex(index: Int, number: Int) {
        interaction.getDefaultRingProtocolImpl().modifyWorshipNumberByIndex(index, number)
    }

    override fun deviceMotorAgingTest(enable: Boolean) {
        interaction.getDefaultRingProtocolImpl().deviceMotorAgingTest(enable)
    }

    override fun getDeviceMotorAgingTestResul() {
        interaction.getDefaultRingProtocolImpl().getDeviceMotorAgingTestResul()
    }

    override fun getTofResult() {
        interaction.getDefaultRingProtocolImpl().getTofResult()
    }

    override fun tofCalibration1() {
        interaction.getDefaultRingProtocolImpl().tofCalibration1()
    }

    override fun tofCalibration2() {
        interaction.getDefaultRingProtocolImpl().tofCalibration2()
    }

    override fun sc01SpeakerAudioTest(audio1Enable: Boolean, audio2Enable: Boolean) {
        interaction.getDefaultRingProtocolImpl().sc01SpeakerAudioTest(audio1Enable, audio2Enable)
    }

    override fun setSc01AudioEnable(audioEnable: Boolean) {
        interaction.getDefaultRingProtocolImpl().setSc01AudioEnable(audioEnable)
    }

    override fun startOTAUpgrade(
        file: File,
        isSafeOTA: Boolean,
        listener: RingOTAUpgradeListener
    ) {
        interaction.getDefaultRingProtocolImpl().startOTAUpgrade(file, isSafeOTA, listener)
    }

    override fun startHDOTAUpgrade(file: File, listener: RingOTAUpgradeListener) {
        interaction.getDefaultRingProtocolImpl().startHDOTAUpgrade(file, listener)
    }

    override fun onConnecting() {
        synchronized(lock) {
            for (appProtocolObserver in appProtocolObservers) {
                appProtocolObserver.onConnecting()
            }
        }
    }

    override fun onConnected() {
        synchronized(lock) {
            for (appProtocolObserver in appProtocolObservers) {
                appProtocolObserver.onConnected()
            }
        }
    }

    override fun onDisconnecting() {
        synchronized(lock) {
            for (appProtocolObserver in appProtocolObservers) {
                appProtocolObserver.onDisconnecting()
            }
        }
    }

    override fun onDisconnected() {
        synchronized(lock) {
            for (appProtocolObserver in appProtocolObservers) {
                appProtocolObserver.onDisconnected()
            }
        }
    }

    override fun onConnectTimeout() {
        synchronized(lock) {
            for (appProtocolObserver in appProtocolObservers) {
                appProtocolObserver.onConnectTimeout()
            }
        }
    }

    override fun requestTimeSync() {
        synchronized(lock) {
            for (appProtocolObserver in appProtocolObservers) {
                appProtocolObserver.requestTimeSync()
            }
        }
    }

    override fun requestStopFindDevice() {
        synchronized(lock) {
            for (appProtocolObserver in appProtocolObservers) {
                appProtocolObserver.requestStopFindDevice()
            }
        }
    }

    override fun onTimeSyncCallback() {
        synchronized(lock) {
            for (appProtocolObserver in appProtocolObservers) {
                appProtocolObserver.onTimeSyncCallback()
            }
        }
    }

    override fun onBatteryPowerCallback(
        status: String,
        bat: String,
        version: String,
        versionName: String,
        buildTime: String
    ) {
        synchronized(lock) {
            for (appProtocolObserver in appProtocolObservers) {
                appProtocolObserver.onBatteryPowerCallback(
                    status,
                    bat,
                    version,
                    versionName,
                    buildTime
                )
            }
        }
    }

    override fun onScreenFlipCallback(isPositive: Boolean) {
        synchronized(lock) {
            for (appProtocolObserver in appProtocolObservers) {
                appProtocolObserver.onScreenFlipCallback(isPositive)
            }
        }
    }

    override fun onDeviceFind() {
        synchronized(lock) {
            for (appProtocolObserver in appProtocolObservers) {
                appProtocolObserver.onDeviceFind()
            }
        }
    }

    override fun onBatteryPowerChangeCallback() {
        synchronized(lock) {
            for (appProtocolObserver in appProtocolObservers) {
                appProtocolObserver.onBatteryPowerChangeCallback()
            }
        }
    }

    override fun onCacheDataCallback(
        startTime: String,
        endTime: String,
        num: Int,
        tick: String,
        endFlag: Int
    ) {
        synchronized(lock) {
            for (appProtocolObserver in appProtocolObservers) {
                appProtocolObserver.onCacheDataCallback(startTime, endTime, num, tick, endFlag)
            }
        }
    }

    override fun onRealTimeCountCallback(
        num: Int,
        tick: String,
        taskStatus: Int,
        currentTaskNumber: Int
    ) {
        synchronized(lock) {
            for (appProtocolObserver in appProtocolObservers) {
                appProtocolObserver.onRealTimeCountCallback(
                    num,
                    tick,
                    taskStatus,
                    currentTaskNumber
                )
            }
        }
    }

    override fun onShutdownCallback() {
        synchronized(lock) {
            for (appProtocolObserver in appProtocolObservers) {
                appProtocolObserver.onShutdownCallback()
            }
        }
    }

    override fun onSettingPrayerRemindersCallback() {
        synchronized(lock) {
            for (appProtocolObserver in appProtocolObservers) {
                appProtocolObserver.onSettingPrayerRemindersCallback()
            }
        }
    }

    override fun onRebootCallback() {
        synchronized(lock) {
            for (appProtocolObserver in appProtocolObservers) {
                appProtocolObserver.onRebootCallback()
            }
        }
    }

    override fun onChantingRemindersSettingCallback() {
        synchronized(lock) {
            for (appProtocolObserver in appProtocolObservers) {
                appProtocolObserver.onChantingRemindersSettingCallback()
            }
        }
    }

    override fun onDataCacheSizeCallback(
        num: Int,
        currentRealTimeNumber: Int,
        currentTaskNumber: Int
    ) {
        synchronized(lock) {
            for (appProtocolObserver in appProtocolObservers) {
                appProtocolObserver.onDataCacheSizeCallback(
                    num,
                    currentRealTimeNumber,
                    currentTaskNumber
                )
            }
        }
    }

    override fun onDeviceConfigInfoCallback(
        isPositive: Boolean,
        isOpenPray: Int,
        chartingStartTime: String,
        chartingEndTime: String,
        light: Int,
        languageType: Int,
        timeInterval: Int,
        supportTaskMode: Boolean,
        taskStatus: Int,
        targetNumber: Int,
        taskId: Int,
        remarks: String,
        protocolVersion: String
    ) {
        synchronized(lock) {
            for (appProtocolObserver in appProtocolObservers) {
                appProtocolObserver.onDeviceConfigInfoCallback(
                    isPositive,
                    isOpenPray,
                    chartingStartTime,
                    chartingEndTime,
                    light,
                    languageType,
                    timeInterval,
                    supportTaskMode,
                    taskStatus,
                    targetNumber,
                    taskId,
                    remarks,
                    protocolVersion
                )
            }
        }
    }

    override fun onDeviceLogCallback() {
        synchronized(lock) {
            for (appProtocolObserver in appProtocolObservers) {
                appProtocolObserver.onDeviceLogCallback()
            }
        }
    }

    override fun onDeviceScreenBrightnessCallback() {
        synchronized(lock) {
            for (appProtocolObserver in appProtocolObservers) {
                appProtocolObserver.onDeviceScreenBrightnessCallback()
            }
        }
    }

    override fun onSettingDeviceLanguageCallback() {
        synchronized(lock) {
            for (appProtocolObserver in appProtocolObservers) {
                appProtocolObserver.onSettingDeviceLanguageCallback()
            }
        }
    }

    override fun onSettingCustomizeConventionCallback() {
        synchronized(lock) {
            for (appProtocolObserver in appProtocolObservers) {
                appProtocolObserver.onSettingCustomizeConventionCallback()
            }
        }
    }

    override fun onSettingStableConventionCallback() {
        synchronized(lock) {
            for (appProtocolObserver in appProtocolObservers) {
                appProtocolObserver.onSettingStableConventionCallback()
            }
        }
    }

    override fun onSettingTasbihTaskCallback() {
        synchronized(lock) {
            for (appProtocolObserver in appProtocolObservers) {
                appProtocolObserver.onSettingTasbihTaskCallback()
            }
        }
    }

    override fun onGetTasbihTaskInfoCallback(
        targetNumber: Int,
        taskId: Int,
        startTime: String,
        endTime: String,
        tick: String
    ) {
        synchronized(lock) {
            for (appProtocolObserver in appProtocolObservers) {
                appProtocolObserver.onGetTasbihTaskInfoCallback(
                    targetNumber,
                    taskId,
                    startTime,
                    endTime,
                    tick
                )
            }
        }
    }

    override fun onSetShipNavigationMode() {
        synchronized(lock) {
            for (appProtocolObserver in appProtocolObservers) {
                appProtocolObserver.onSetShipNavigationMode()
            }
        }
    }

    override fun onSetScreenRestTime() {
        synchronized(lock) {
            for (appProtocolObserver in appProtocolObservers) {
                appProtocolObserver.onSetScreenRestTime()
            }
        }
    }

    override fun onSetPrayerRemindConfig() {
        synchronized(lock) {
            for (appProtocolObserver in appProtocolObservers) {
                appProtocolObserver.onSetPrayerRemindConfig()
            }
        }
    }

    override fun onSetCustomCountReminder() {
        synchronized(lock) {
            for (appProtocolObserver in appProtocolObservers) {
                appProtocolObserver.onSetCustomCountReminder()
            }
        }
    }

    override fun onGetPrayerRemindConfig(
        restTime: Int,
        configs: Array<Array<Int>>,
        normal33: Boolean,
        normal100: Boolean,
        customValue: Int
    ) {
        synchronized(lock) {
            for (appProtocolObserver in appProtocolObservers) {
                appProtocolObserver.onGetPrayerRemindConfig(
                    restTime,
                    configs,
                    normal33,
                    normal100,
                    customValue
                )
            }
        }
    }

    override fun onSetUserInfo() {
        synchronized(lock) {
            for (appProtocolObserver in appProtocolObservers) {
                appProtocolObserver.onSetUserInfo()
            }
        }
    }

    override fun onGetCurrentStep(step: Int) {
        synchronized(lock) {
            for (appProtocolObserver in appProtocolObservers) {
                appProtocolObserver.onGetCurrentStep(step)
            }
        }
    }

    override fun onGetAllSleepData() {
        synchronized(lock) {
            for (appProtocolObserver in appProtocolObservers) {
                appProtocolObserver.onGetAllSleepData()
            }
        }
    }

    override fun onGetAllStepData() {
        synchronized(lock) {
            for (appProtocolObserver in appProtocolObservers) {
                appProtocolObserver.onGetAllStepData()
            }
        }
    }

    override fun onPkeyOperation(pkey: String) {
        synchronized(lock) {
            for (appProtocolObserver in appProtocolObservers) {
                appProtocolObserver.onPkeyOperation(pkey)
            }
        }
    }

    override fun onGsensorTest(gsensorId: Int, status: Int, datas: Array<Int>) {
        synchronized(lock) {
            for (appProtocolObserver in appProtocolObservers) {
                appProtocolObserver.onGsensorTest(gsensorId, status, datas)
            }
        }
    }

    override fun onGSensorDataReport(datetime: String, packageIndex: Int, datas: Array<String>) {
        synchronized(lock) {
            for (appProtocolObserver in appProtocolObservers) {
                appProtocolObserver.onGSensorDataReport(
                    datetime,
                    packageIndex,
                    datas
                )
            }
        }
    }

    override fun onGetWorshipCacheData(
        updateTime: String,
        fajrCount: Int,
        dhuhrCount: Int,
        asrCount: Int,
        maghribCount: Int,
        ishaCount: Int,
        tick: String,
        endFlag: Int
    ) {
        synchronized(lock) {
            for (appProtocolObserver in appProtocolObservers) {
                appProtocolObserver.onGetWorshipCacheData(
                    updateTime,
                    fajrCount,
                    dhuhrCount,
                    asrCount,
                    maghribCount,
                    ishaCount,
                    tick,
                    endFlag
                )
            }
        }
    }

    override fun onGetRealtimeWorship(count: Int) {
        synchronized(lock) {
            for (appProtocolObserver in appProtocolObservers) {
                appProtocolObserver.onGetRealtimeWorship(
                    count
                )
            }
        }
    }

    override fun onSetLedTimeAndLight() {
        synchronized(lock) {
            for (appProtocolObserver in appProtocolObservers) {
                appProtocolObserver.onSetLedTimeAndLight()
            }
        }
    }

    override fun onGetSc01DeviceInfo(
        battery: Int,
        lightTime: Int,
        light: Int,
        protocolVersion: String,
        softwareVersion: String,
        audioEnable: Boolean
    ) {
        synchronized(lock) {
            for (appProtocolObserver in appProtocolObservers) {
                appProtocolObserver.onGetSc01DeviceInfo(
                    battery, lightTime, light, protocolVersion, softwareVersion, audioEnable
                )
            }
        }
    }

    override fun onDeviceInfraRedTest(enable: Boolean) {
        synchronized(lock) {
            for (appProtocolObserver in appProtocolObservers) {
                appProtocolObserver.onDeviceInfraRedTest(
                    enable
                )
            }
        }
    }

    override fun onDeviceRadarTest(enable: Boolean) {
        synchronized(lock) {
            for (appProtocolObserver in appProtocolObservers) {
                appProtocolObserver.onDeviceRadarTest(
                    enable
                )
            }
        }
    }

    override fun onGetAllWorshipCacheData(count: Int) {
        synchronized(lock) {
            for (appProtocolObserver in appProtocolObservers) {
                appProtocolObserver.onGetAllWorshipCacheData(
                    count
                )
            }
        }
    }

    override fun onModifyWorshipNumberByIndex(success: Boolean) {
        synchronized(lock) {
            for (appProtocolObserver in appProtocolObservers) {
                appProtocolObserver.onModifyWorshipNumberByIndex(
                    success
                )
            }
        }
    }

    override fun onDeviceMotorAgingTest(enable: Boolean) {
        synchronized(lock) {
            for (appProtocolObserver in appProtocolObservers) {
                appProtocolObserver.onDeviceMotorAgingTest(
                    enable
                )
            }
        }
    }

    override fun onGetDeviceMotorAgingTestResul() {
        synchronized(lock) {
            for (appProtocolObserver in appProtocolObservers) {
                appProtocolObserver.onGetDeviceMotorAgingTestResul()
            }
        }
    }

    override fun onGetTofResult(status: Int, distance: Int) {
        synchronized(lock) {
            for (appProtocolObserver in appProtocolObservers) {
                appProtocolObserver.onGetTofResult(status, distance)
            }
        }
    }

    override fun onTofCalibration1(status: Int) {
        synchronized(lock) {
            for (appProtocolObserver in appProtocolObservers) {
                appProtocolObserver.onTofCalibration1(status)
            }
        }
    }

    override fun onTofCalibration2(status: Int) {
        synchronized(lock) {
            for (appProtocolObserver in appProtocolObservers) {
                appProtocolObserver.onTofCalibration2(status)
            }
        }
    }

    override fun onSc01SpeakerAudioTest() {
        synchronized(lock) {
            for (appProtocolObserver in appProtocolObservers) {
                appProtocolObserver.onSc01SpeakerAudioTest()
            }
        }
    }

    override fun onSetSc01AudioEnable() {
        synchronized(lock) {
            for (appProtocolObserver in appProtocolObservers) {
                appProtocolObserver.onSetSc01AudioEnable()
            }
        }
    }
}